/*
 * RpcClient.cpp
 *
 *  Created on: Nov 4, 2015
 *      Author: rpi
 */

#include <iostream>
#include "RpcClient.h"

RpcClient::RpcClient(std::string stdIpAddr, unsigned short usPort)
	: _tcpClient(stdIpAddr, usPort)
	, _iSequence(0)
{
	if (!_tcpClient.Connect())
	{
		std::cerr << "Cannot connect to remote peer!" << std::endl;
		exit(EXIT_FAILURE);
	}
}

RpcClient::~RpcClient()
{
	_tcpClient.Close();
}

bool RpcClient::request(std::string stdCmd, Json::Value &joParam,
		Json::Value &joResp)
{
	Json::Value joQuery;
	Json::FastWriter joWriter;
	std::string strQuery;
	std::string strResponse;

	/* build JSON-RPC query */
	joQuery["jsonrpc"] = "2.0";
	joQuery["id"] = ++_iSequence;
	joQuery["method"] = stdCmd;
	joQuery["params"] = joParam;
	strQuery = joWriter.write(joQuery);
	std::cout << "RPC Request: " << strQuery << std::endl;

	if (_tcpClient.Send(strQuery) == -1)
	{
		std::cerr << "Error while sending data!" << std::endl;
		return false;
	}

	/* wait the response */
	if (_tcpClient.Recv(strResponse) == -1)
	{
		std::cerr << "Error while receiving data!" << std::endl;
		return false;
	}
	std::cout << "RPC Received: " << strResponse << std::endl;

	Json::Reader oReader;
	if (!oReader.parse(strResponse, joResp))
	{
		std::cout << "RPC Error Response: " << strResponse << std::endl;
		return false;
	}

	return true;
}

bool RpcClient::request(std::string stdCmd, Json::Value &joResp)
{
	Json::Value joQuery;
	Json::FastWriter joWriter;
	std::string strQuery;
	std::string strResponse;

	/* build JSON-RPC query */
	joQuery["jsonrpc"] = "2.0";
	joQuery["id"] = ++_iSequence;
	joQuery["method"] = stdCmd;
	strQuery = joWriter.write(joQuery);
	std::cout << "RPC Request: " << strQuery << std::endl;

	if (_tcpClient.Send(strQuery) == -1)
	{
		std::cerr << "Error while sending data!" << std::endl;
		return false;
	}

	/* wait the response */
	if (_tcpClient.Recv(strResponse) == -1)
	{
		std::cerr << "Error while receiving data!" << std::endl;
		return false;
	}
	std::cout << "RPC Received: " << strResponse << std::endl;

	Json::Reader oReader;
	if (!oReader.parse(strResponse, joResp))
	{
		std::cout << "RPC Error Response: " << strResponse << std::endl;
		return false;
	}

	return true;
}
